/******************************************
 * Nombre del archivo: Cond.java
 * Universidad del Valle de Guatemala
 * Curso: Algoritmos y Estructura de Datos
 * Autores:
 *      * Martín Guzmán     08041
 *      * David Hsieh       08225
 *      * Eduardo Mejicano  08058
 *      * Kevin Sánchez     08302
 * Fecha: 16 de agosto de 2009
 * Descripción:
*******************************************/

import java.util.LinkedList;
import java.util.ArrayList;

public class Cond {
    private String Else = "";
    private String Resultado="";
    public Cond(String cadena_condicion){
        //System.out.println("intenta ser entrar a condición COND");
        //System.out.println("CONDICION: ."+cadena_condicion+".");
        //la sintaxis de la función es correcta.. procede a ingresarla
        if(Verificar(cadena_condicion)==true){
            //System.out.println("aaaaaaaaa");
            ArrayList<String> listas = Arreglar_texto(cadena_condicion.substring(2,cadena_condicion.length()-1));
            /*//todo quitar esto---------
            for(int i=0;i<listas.size();i++){
                System.out.println("."+listas.get(i)+".");
            }
            */
            
            listas.remove(0);//quita la palabra COND
            // ya solo quedan las condiciones a evaluar...
            String a=listas.get(listas.size()-1);
            String temporal_ultima_de_lista= a.substring(2,a.length()-1);
            At_Lista ultimo = new At_Lista(temporal_ultima_de_lista);
            //System.out.println("bbbbbbbbbbbb");

            try{
                Else = ultimo.Obtener_valor();
                //System.out.println("cccccccc");


            }catch(Exception ex){
                //si solo hay un elemento, es un valor, por lo que devuelve el Else un valor
                if(Arreglar_texto(temporal_ultima_de_lista).size()==1){
                    Else = temporal_ultima_de_lista;
                }
                else{
                    Else="NIL";
                }
            }
            
            //System.out.println("Else: "+Else);
            //ya está guardada la última condición, el else..
            int numero_temporal=listas.size()-1;
            if(Else.compareToIgnoreCase("NIL")==0){
                numero_temporal=listas.size();
            }
            

            for(int i=0;i<numero_temporal;i++){
                String b =listas.get(i);

                //System.out.println("B: "+b);//Temporal

                ArrayList<String> sub_lista = Arreglar_texto(b.substring(2,b.length()-1));
                //System.out.println("largo de sublista: "+sub_lista.size());//Temporal

                if(sub_lista.size()==1){
                    At_Lista temporal1 = new At_Lista(sub_lista.get(0).substring(2,sub_lista.get(0).length()-1));
                    if(temporal1.Obtener_valor().compareToIgnoreCase("T")==0)
                        Resultado="NIL";
                    else
                        System.out.println("The condition in the COND is not boolean");
                }
                else if(sub_lista.size()==2){

                    Atomo temporal1 = null;
                    //System.out.println("aca");


                    if(sub_lista.get(0).startsWith("(")){
                        temporal1 = new At_Lista(sub_lista.get(0).substring(2,sub_lista.get(0).length()-1));
                    }
                    else if(Lista_Variables.getValor(sub_lista.get(0))!=null){
                        temporal1 = new At_Variable(Lista_Variables.getValor(sub_lista.get(0)));
                    }
                    

                    String super_temporal="";
                    try{
                        if(temporal1.Obtener_valor().compareToIgnoreCase("T")==0)
                            super_temporal="T";
                        else if(temporal1.Obtener_valor().compareToIgnoreCase("NIL")==0)
                            super_temporal="NIL";
                    }
                    catch(Exception ex){
                        System.out.println("The condition in the COND is not boolean");
                    }
                    // puede ser un valor o una lista...
                    String variable=sub_lista.get(1);
                    Atomo temporal2 = null;
                    if(sub_lista.get(1).startsWith("(")){
                        variable=sub_lista.get(1).substring(2,sub_lista.get(1).length()-1);
                        temporal2 = new At_Lista(variable);
                    }
                    else{
                        temporal2 = new At_Variable(variable);
                    }

                    try{
                        if(super_temporal.compareToIgnoreCase("T")==0)
                            Resultado=temporal2.Obtener_valor();
                    }catch(Exception ex){
                        System.out.println("Error in the condition");
                    }

                }
                if(Resultado.compareToIgnoreCase("")!=0){
                    break;
                }
            }
            if(Resultado.compareToIgnoreCase("")==0){
                    Resultado=Else;
            }

            //System.out.println("Resultado: "+Resultado);

        }
        //sintaxis incorrecta de la función
        else{
            System.out.println("An error has ocurred. Cond sintaxis is not correct.");
        }

    }

    public String Obtener_valor(){
        return Resultado;
    }
    
    
    public boolean Verificar(String cadena_condicion){
        if(cadena_condicion.startsWith("(") && cadena_condicion.endsWith(")")){
            ArrayList<String> listas = Arreglar_texto(cadena_condicion.substring(2,cadena_condicion.length()-1));
            //TODO quitar esto //debugear
            /*
            for(int i=0;i<listas.size();i++){
                System.out.println("."+listas.get(i)+".");
            }*/
            //System.out.println("cantidad de condiciones: ."+listas.size()+".");
            //tiene que empezar con la palabra COND
            if(listas.get(0).compareToIgnoreCase("COND")!=0){
                System.out.println("In a condition the first element has to be the world COND");
                return false;
            }

            //todo adentro de un cond tiene que ser una lista, de lo contrario no funciona
            //(COND  ((< 1 2)(+ 1 2))  ((= 1 2)  (+ 2 3))  (2))
            for(int i=1;i<listas.size();i++){
                if(listas.get(i).startsWith("(")==false || listas.get(i).endsWith(")")==false){
                    System.out.println("In a COND statement all the conditions has to be lists");
                    return false;
                }
            }

            int cantidad_condiciones=listas.size()-1;
            //falta evaluar cada condición y en base a eso, el resultado...


            //cada condición solo puede tener 2 cosas.. la condición y el resultado (o bien solo la condición):
            //(  (= A B)  (+ A B) )
            for(int i=1;i<listas.size()-1;i++){

                String texto_temporal= listas.get(i);
                String texto_temporal2=texto_temporal.substring(2,texto_temporal.length()-1);
                if(Arreglar_texto(texto_temporal2).size()>2){
                    System.out.println("You can't have more than 2 atoms in a condition");
                    return false;
                }
            }
            //si pasó las pruebas anteriores
            return true;

        }
        return false;
    }
    
    
    /*****************************************
     * Método: Arreglar_texto
     * Autor: Martín Guzmán
     * Uso: divide en átomos el texto
     * Retorno: guarda los átomos en una lista.
     *****************************************/
    public ArrayList<String> Arreglar_texto(String texto_lista){
        String[] temporal=texto_lista.split(",");

        //pasar a una lista el arreglo de strings
        ArrayList<String> temporal_lista = new ArrayList<String>();
        for(int i=0;i<temporal.length;i++)
        {
            temporal_lista.add(temporal[i]);
        }
        //***********************************
        ArrayList<String> temporal_a_agregar = new ArrayList<String>();
        for(int i=0;i<temporal_lista.size();i++)
        {
            String sub_cadena=temporal_lista.get(i);
            if (temporal_lista.get(i).startsWith("("))//agrupar hasta que se cierre este paréntesis
            {
                int parentesis=1;
                int posicion=i;
                for(int j=i+1;j<temporal_lista.size();j++){
                    if(temporal[j].contains(")"))
                        parentesis--;
                    if (parentesis==0){
                        posicion=j;
                        break;
                    }
                    if(temporal[j].startsWith("("))
                        parentesis++;

                }
                sub_cadena="";
                //System.out.println("i"+i+" j:"+posicion);//TODO quitar esto
                for(int a=i;a<=posicion;a++){
                   sub_cadena+=","+temporal_lista.get(a);
                }
                sub_cadena=sub_cadena.substring(1, sub_cadena.length());//para quitarle la última ","
                i=posicion;
            }
            //System.out.println("Sub-cadena: ."+sub_cadena+".");//TODO quitar esto
            temporal_a_agregar.add(sub_cadena);
        }
        return temporal_a_agregar;
    }
}

